﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LitJson;
using AxZWANPHONELib;

using TopVisionLog;

namespace TopVisionVideoStream
{
    public class QosResolution
    {
        public int Width;
        public int Height;

        public override string ToString()
        {
            return Width + " x " + Height;
        }
    }

    public class Qos
    {
        class QosAudioInfo
        {
            /// <summary>
            /// 
            /// </summary>
            public string CurFractionLost { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string TotalFractionLost { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string CurJitter { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string CurBitrate { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string AvgBitrate { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string CurRTT { get; set; }
        }
        class QosVideoDownInfo
        {
            /// <summary>
            /// 
            /// </summary>
            public string CurFractionLost { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string TotalFractionLost { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string CurJitter { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string CurBitrate { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string AvgBitrate { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string CurRTT { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string RecvFrameRate { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string DisplayFrameRate { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string RealESBitRate_Cur { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string RealESBitRate_Avg { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string Resolution { get; set; }
        }
        class QosVideoUpInfo
        {
            /// <summary>
            /// 
            /// </summary>
            public string CurFractionLost { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string TotalFractionLost { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string CurJitter { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string CurBitrate { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string AvgBitrate { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string CurRTT { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string RealCapFrameRate { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string RealFrameRate { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string RealESBitRate_Cur { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string RealESBitRate_Avg { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string Resolution { get; set; }
        }

        QosAudioInfo QosAudioDownData;
        QosAudioInfo QosAudioUpData;

        QosVideoDownInfo QosVideoDownData;
        QosVideoUpInfo QosVideoUpData;

        private QosResolution qosResolution;

        private bool doQos = false;

        #region 属性


        #region 视频

        /// <summary>
        /// 下行视频分辨率
        /// </summary>
        public QosResolution QosDownResolutionData
        {
            get
            {
                if (qosResolution == null)
                {
                    qosResolution = new QosResolution { Width = 0, Height = 0 };
                }
                if (QosVideoDownData != null)
                {
                    qosResolution.Width = int.Parse(QosVideoDownData.Resolution.Split('*')[0]);
                    qosResolution.Height = int.Parse(QosVideoDownData.Resolution.Split('*')[1]);
                }
                return qosResolution;
            }
        }
        /// <summary>
        /// 上行视频分辨率
        /// </summary>
        public QosResolution QosUpResolutionData
        {
            get
            {
                var _rsl = new QosResolution { };
                if (QosVideoUpData != null)
                {
                    _rsl.Width = int.Parse(QosVideoUpData.Resolution.Split('*')[0]);
                    _rsl.Height = int.Parse(QosVideoUpData.Resolution.Split('*')[1]);
                }
                return _rsl;
            }
        }

        /// <summary>
        /// 下行祯数
        /// </summary>
        public int QosDownFPS
        {
            get
            {
                int _fps = 0;

                if (QosVideoDownData != null)
                {
                    _fps = int.Parse(QosVideoDownData.RecvFrameRate.Trim());
                }

                return _fps;
            }
        }
        /// <summary>
        /// 上行祯数
        /// </summary>
        public int QosUpFPS
        {
            get
            {
                int _fps = 0;

                if (QosVideoUpData != null)
                {
                    _fps = int.Parse(QosVideoUpData.RealFrameRate.Trim());
                }

                return _fps;
            }
        }
        /// <summary>
        /// 下行码率[kbps]
        /// </summary>
        public int QosDownVideoBitrate
        {
            get
            {
                int _bitrate = 0;

                if (QosVideoDownData != null)
                {
                    _bitrate = int.Parse(QosVideoDownData.CurBitrate.Trim());
                }

                return _bitrate;
            }
        }
        /// <summary>
        /// 下行码率[kbps]
        /// </summary>
        public int QosDownRealESBitRate_Cur
        {
            get
            {
                int _bitrate = 0;

                if (QosVideoDownData != null)
                {
                    _bitrate = int.Parse(QosVideoDownData.RealESBitRate_Cur.Trim());
                }

                return _bitrate;
            }
        }
        public int QosDownVideoBitrateAvg
        {
            get
            {
                int _bitrate = 0;

                if (QosVideoDownData != null)
                {
                    _bitrate = int.Parse(QosVideoDownData.RealESBitRate_Avg.Trim());
                }

                return _bitrate;
            }
        }

        /// <summary>
        /// 上行码率[kbps]
        /// </summary>
        public int QosUpVideoBitrate
        {
            get
            {
                int _bitrate = 0;

                if (QosVideoUpData != null)
                {
                    _bitrate = int.Parse(QosVideoUpData.CurBitrate.Trim());
                }

                return _bitrate;
            }
        }

        public int QosUpRealESBitRate_Cur
        {
            get
            {
                int _bitrate = 0;

                if (QosVideoUpData != null)
                {
                    _bitrate = int.Parse(QosVideoUpData.RealESBitRate_Cur.Trim());
                }

                return _bitrate;
            }
        }

        public int QosUpRealESBitRate_Avg
        {
            get
            {
                int _bitrate = 0;

                if (QosVideoUpData != null)
                {
                    _bitrate = int.Parse(QosVideoUpData.RealESBitRate_Avg.Trim());
                }

                return _bitrate;
            }
        }

        /// <summary>
        /// 视频下行网络延时[ms]
        /// </summary>
        public int QosDownVideoNetworkDelay
        {
            get
            {
                int _delay = 0;

                if (QosVideoDownData != null)
                {
                    _delay = int.Parse(QosVideoDownData.CurRTT.Trim());
                }

                return _delay;
            }
        }
        /// <summary>
        /// 视频上行网络延时[ms]
        /// </summary>
        public int QosUpVideoNetworkDelay
        {
            get
            {
                int _delay = 0;

                if (QosVideoUpData != null)
                {
                    _delay = int.Parse(QosVideoUpData.CurRTT.Trim());
                }

                return _delay;
            }
        }
        /// <summary>
        /// 视频下行当前丢包
        /// </summary>
        public int QosDownVideoLost
        {
            get
            {
                int _lost = 0;

                if (QosVideoDownData != null)
                {
                    _lost = int.Parse(QosVideoDownData.CurFractionLost.Trim());
                }

                return _lost;
            }
        }
        /// <summary>
        /// 视频下行总丢包
        /// </summary>
        public int QosDownVideoTotalLost
        {
            get
            {
                int _lost = 0;

                if (QosVideoDownData != null)
                {
                    _lost = int.Parse(QosVideoDownData.TotalFractionLost.Trim());
                }

                return _lost;
            }
        }
        /// <summary>
        /// 视频上行当前丢包
        /// </summary>
        public int QosUpVideoLost
        {
            get
            {
                int _lost = 0;

                if (QosVideoUpData != null)
                {
                    _lost = int.Parse(QosVideoUpData.CurFractionLost.Trim());
                }

                return _lost;
            }
        }
        /// <summary>
        /// 视频上行总丢包
        /// </summary>
        public int QosUpVideoTotalLost
        {
            get
            {
                int _lost = 0;

                if (QosVideoUpData != null)
                {
                    _lost = int.Parse(QosVideoUpData.TotalFractionLost.Trim());
                }

                return _lost;
            }
        }


        #endregion


        #region 音频

        /// <summary>
        /// 下行码率[kbps]
        /// </summary>
        public int QosDownAudioBitrate
        {
            get
            {
                int _bitrate = 0;

                if (QosAudioDownData != null)
                {
                    _bitrate = int.Parse(QosAudioDownData.CurBitrate.Trim());
                }

                return _bitrate;
            }
        }
        /// <summary>
        /// 上行码率[kbps]
        /// </summary>
        public int QosUpAudioBitrate
        {
            get
            {
                int _bitrate = 0;

                if (QosAudioUpData == null || QosAudioUpData.CurBitrate == null) return 0;

                _bitrate = int.Parse(QosAudioUpData.CurBitrate.Trim());

                return _bitrate;
            }
        }
        /// <summary>
        /// 音频下行当前丢包
        /// </summary>
        public int QosDownAudioLost
        {
            get
            {
                int _lost = 0;

                if (QosAudioDownData != null)
                {
                    _lost = int.Parse(QosAudioDownData.CurFractionLost.Trim());
                }

                return _lost;
            }
        }
        /// <summary>
        /// 音频下行总丢包
        /// </summary>
        public int QosDownAudioTotalLost
        {
            get
            {
                int _lost = 0;

                if (QosAudioDownData != null)
                {
                    _lost = int.Parse(QosAudioDownData.TotalFractionLost.Trim());
                }

                return _lost;
            }
        }
        /// <summary>
        /// 音频上行当前丢包
        /// </summary>
        public int QosUpAudioLost
        {
            get
            {
                int _lost = 0;

                if (QosAudioUpData != null)
                {
                    _lost = int.Parse(QosAudioUpData.CurFractionLost.Trim());
                }

                return _lost;
            }
        }
        /// <summary>
        /// 音频上行总丢包
        /// </summary>
        public int QosUpAudioTotalLost
        {
            get
            {
                int _lost = 0;

                if (QosAudioUpData != null)
                {
                    _lost = int.Parse(QosAudioUpData.TotalFractionLost.Trim());
                }

                return _lost;
            }
        }
        /// <summary>
        /// 音频下行网络延时[ms]
        /// </summary>
        public int QosDownAudioNetworkDelay
        {
            get
            {
                int _delay = 0;

                if (QosAudioDownData != null)
                {
                    _delay = int.Parse(QosAudioDownData.CurRTT.Trim());
                }

                return _delay;
            }
        }
        /// <summary>
        /// 音频上行网络延时[ms]
        /// </summary>
        public int QosUpAudioNetworkDelay
        {
            get
            {
                int _delay = 0;

                if (QosAudioUpData != null)
                {
                    _delay = int.Parse(QosAudioUpData.CurRTT.Trim());
                }

                return _delay;
            }
        }

        #endregion


        #endregion

        public void StartQos()
        {
            TVLog.WriteLine("[QOS]开始获取QOS");
#if DEBUG
            Console.WriteLine("[QOS]开始获取QOS");
#endif
            //var core = Configuration.Core;
            //core.QosInfoResult += Core_QosInfoResult;
            if (!doQos)
            {
                doQos = true;
                DoQos();
            }
        }

        public void StopQos()
        {
            if (doQos)
            {
                TVLog.WriteLine("[QOS]停止获取QOS");

#if DEBUG
                Console.WriteLine("[QOS]停止获取QOS");
#endif
                //var core = Configuration.Core;
                //core.QosInfoResult -= Core_QosInfoResult;

                qosResolution = null;
                QosVideoDownData = null;
                QosVideoUpData = null;
                QosAudioDownData = null;
                QosAudioUpData = null;
                doQos = false;
            }
        }

        private async void DoQos()
        {
            var core = Configuration.Core;

            core.QosInfoResult += Core_QosInfoResult;

            while (doQos)
            {
                core.bGetQosInfo();

                await Task.Delay(1000);
            }

            core.QosInfoResult -= Core_QosInfoResult;
        }

        private void Core_QosInfoResult(object sender, _DZwanPhoneEvents_QosInfoResultEvent e)
        {
            string audiodown = e.audiodown;
            string audioup = e.audioup;
            string videodown = e.videodown;
            string videoup = e.videoup;
            try
            {
                QosAudioDownData = audiodown.Split(',').ArrayToObject<QosAudioInfo>();
                QosAudioUpData = audioup.Split(',').ArrayToObject<QosAudioInfo>();
                QosVideoDownData = videodown.Split(',').ArrayToObject<QosVideoDownInfo>();
                QosVideoUpData = videoup.Split(',').ArrayToObject<QosVideoUpInfo>();
            }
            catch (Exception ex)
            {
                TVLog.WriteLine("[ERROR]解析QOS异常:" + ex.Message);
            }
        }
    }
}
